﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;

namespace FPSO.Models.TagMapping
{
    public class TagProp
    {
		private PropertyInfo Prop;
		internal object Container { get; private set; }

		/// <summary>
		/// 标签ID
		/// </summary>
		public long TagID { get; set; }
		/// <summary>
		/// 标签名称
		/// </summary>
		public string TagName { get; private set; }

		/// <summary>
		/// 字段映射属性
		/// </summary>
		public FieldMapperAttribute FieldMap { get; private set; }

		public TagProp(string tagName, PropertyInfo prop, object container, FieldMapperAttribute fieldMap)
		{
			TagID = 0;
			TagName = tagName;
			Prop = prop;
			Container = container;
			FieldMap = fieldMap;
		}

		public void SetValue(TagValue value)
		{
			if (FieldMap.IsTStamp)
			{
				Prop.SetValue(Container, value.TStamp);
				return;
			}

			double val = Convert.ToDouble(value.Value) * FieldMap.Coefficient;
			switch (Type.GetTypeCode(Prop.PropertyType))
			{
				case TypeCode.Int32: Prop.SetValue(Container, Convert.ToInt32(val)); break;
				case TypeCode.Int64: Prop.SetValue(Container, Convert.ToInt64(val)); break;
				case TypeCode.Double:
					{
						if(val > 99.0)
							val = 0;
                        Prop.SetValue(Container, val); 
						break;
                    }
                case TypeCode.Boolean: Prop.SetValue(Container, Math.Abs(val) > 0.001); break;
				default: throw new Exception("错误的目标数据类型");
			}
		}

		//通过multi_coef设置是否需要考虑乘单位系数，通常仅在获取通讯数据后第一次需要乘FieldMap.Coefficient，其余均不需要
		public void SetValue(double value,bool multi_coef)
        {
			//待测试，OPC地址值需要*0.001，但软件计算结果不需要做精度换算，这里先不换算，可能有问题
			//绑定的控件可以通过计算结果赋值，避免精度换算
			double coef = 1.0;
			if(multi_coef)
				coef = FieldMap.Coefficient;
			double val = Convert.ToDouble(value) * coef;
            switch (Type.GetTypeCode(Prop.PropertyType))
            {
                case TypeCode.Int32: Prop.SetValue(Container, Convert.ToInt32(val)); break;
                case TypeCode.Int64: Prop.SetValue(Container, Convert.ToInt64(val)); break;
                case TypeCode.Double: Prop.SetValue(Container, val); break;
				case TypeCode.Single: Prop.SetValue(Container, val); break;
				case TypeCode.Boolean:
					{
						bool check = Math.Abs(val) > 0.001;
						Prop.SetValue(Container, check); 
						break;
					}
				default: throw new Exception("错误的目标数据类型");
            }
        }
    }
}
